﻿Public Class Launcher

#Region "Variables"
    Dim Override As Boolean = False
    Dim prognames(500) As String
    ''' <prognames>
    ''' Array storing all names of programs
    ''' </prognames>
    Dim checkprognames As New ArrayList
    ''' <checkprognames>
    ''' Useed to check that all the programs in My.Settings.prognames are still to be launched
    ''' </checkprognames>
    Dim progdirs(500) As String
    ''' <progdirs>
    ''' Array storing all directorys of programs
    ''' </progdirs>
    ''' 
    Dim progexts(500) As String
    Dim NextProgInt As Integer
    ''' <NextProgInt>
    ''' The index of the next program to be launched
    ''' </NextProgInt>
    Dim totalprogs As Integer
    ''' <totalprogs>
    ''' The total number of programs
    ''' </totalprogs>
    Dim progsleft As Integer
    ''' <progsleft>
    ''' The number of programs left to launch
    ''' </progsleft>
    Dim closeme As Boolean = False
    ''' <closeme>
    ''' Is the form allowed to close
    ''' </closeme>
    Dim progsleftlist As New ArrayList
    ''' <progsleftlist>
    ''' List of programs still to launch
    ''' </progsleftlist>
    Dim progsleftlistchange As Boolean = False
    ''' <progsleftlistchange>
    ''' Has the above list changed?
    ''' </progsleftlistchange>
    Dim status As String = "Loading Startup Manager"
    ''' <status>
    ''' The string that is displayed in the main label
    ''' </status>
    Dim lastlaunchedprogram As String
    ''' <lastlaunchedprogram>
    ''' What was the name of the last program to be launched?
    ''' </lastlaunchedprogram>
    Dim intaskbar As Boolean = False
    ''' <intaskbar>
    ''' Has the program been minimized to the taskbar?
    ''' </intaskbar>
    Dim progress As Integer
    ''' <progress>
    ''' The position of the progress bar
    ''' </progress>
    Dim waiting As Boolean = False

    Dim overrideenabled As Boolean = False
    Dim launchallenabled As Boolean = False
    Dim launcherthread As Threading.Thread

    ''' <waiting>
    ''' Are we waiting for something? (Used for progress bar
    ''' </waiting>
    Dim waitingreason As waitingreasonenum

    ''' <waitingreason>
    ''' Why are we waiting? ENUM
    ''' </waitingreason>
    ''' 

    Enum waitingreasonenum
        cpu
        disk
    End Enum
#End Region

    Private Sub Launcher_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If closeme = False Then
            e.Cancel = True
        End If
    End Sub

    Private Sub Launcher_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'My.Settings.progdirs.Clear()
        'My.Settings.progexts.Clear()
        'My.Settings.prognames.Clear()
        'My.Settings.Save()
        If My.Settings.progdirs Is Nothing Then
            My.Settings.progdirs = New ArrayList
        End If
        If My.Settings.progexts Is Nothing Then
            My.Settings.progexts = New ArrayList
        End If
        If My.Settings.prognames Is Nothing Then
            My.Settings.prognames = New ArrayList
        End If
        If My.Settings.CorrectedNames Is Nothing Then
            My.Settings.CorrectedNames = New ArrayList
        End If
        If My.Settings.CorrectedDirectories Is Nothing Then
            My.Settings.CorrectedDirectories = New ArrayList
        End If
        If My.Settings.CorrectedExtensions Is Nothing Then
            My.Settings.CorrectedExtensions = New ArrayList
        End If

        Dim startthread As New Threading.Thread(AddressOf Start)
        startthread.Start()
    End Sub

    Sub Start()
        status = "Initializing Startup Manager"
        For i = 1 To 1000
            progress = i / 2
            System.Threading.Thread.Sleep(20)
        Next
        Try
            If My.Computer.Registry.LocalMachine.OpenSubKey("Software\Startup Manager\").GetValue("Version") = My.Application.Info.Version.ToString Then
                AddtoArrays()
                launcherthread = New Threading.Thread(AddressOf Launcher)
                launcherthread.Start()
            Else
                CHECK()
            End If
        Catch
            If Not My.Computer.Registry.LocalMachine.OpenSubKey("Software").GetSubKeyNames.Contains("Startup Manager") Then
                CHECK()
                Exit Try
            End If
            AddtoArrays()
            launcherthread = New Threading.Thread(AddressOf Launcher)
            launcherthread.Start()
        End Try
    End Sub

    Sub MovefromUserRegistry()
        Dim names() As String = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").GetValueNames()
        If My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").ValueCount > 1 Then
searchreg:  Try
                For i As Integer = 0 To My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").ValueCount - 1
                    Dim keyvalue As String
                    keyvalue = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").GetValue(names(i))
                    If Not names(i) = "Default" Then
                        My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup", True).SetValue(names(i), keyvalue)
                        My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", True).DeleteValue(names(i))
                    End If
                Next
            Catch
                My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", True).CreateSubKey("Managed Startup")
                GoTo searchreg
            End Try
        End If
    End Sub

    Sub MovefromUserStartMenu()
        Dim path As String = My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"
        Dim startnames() As String = System.IO.Directory.GetFiles(path)
        Dim name As String = ""
        If Not startnames.Length = 0 Then
movestartmenu: Try
                For i As Integer = 0 To startnames.Length - 1
                    name = startnames(i).Substring(path.Length)
                    System.IO.File.Move(My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\" & name, _
                                        My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Managed Startup\" & name)
                Next
            Catch ex As Exception
                If ex.Message.StartsWith("Cannot create a file") Then
                    System.IO.File.Delete(My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Managed Startup\" & Name)
                    GoTo movestartmenu
                End If
                System.IO.Directory.CreateDirectory(My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Managed Startup\")
                GoTo movestartmenu
            End Try
        End If
    End Sub

    Sub AddCurrentUserRegistry()
loadfromregistry:  'Add Current User Registry
        status = "Searching User Registry"
        Dim keynames() As String = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValueNames
        For Each Name As String In keynames
checkformarks: For i = 0 To My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(Name).Length - 1
                If My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(Name).Chars(i) = """"c Then
                    My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup", True).SetValue(Name, My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(Name).Remove(i, 1))
                    GoTo checkformarks
                End If
            Next
        Next
        Try
            For Each KeyName As String In keynames
                If Not KeyName = "" Then
                    checkprognames.Add(KeyName)
                    If Not My.Settings.prognames.Contains(KeyName) Then
                        Dim ProgramDetails As New ProgramDetails
                        ProgramDetails.Name = KeyName
                        ProgramDetails.Directory = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(ProgramDetails.Name)
                        For i As Integer = 0 To ProgramDetails.Directory.Length - 1
                            Try
                                If ProgramDetails.Directory.Chars(i) = "/" Then
                                    For x As Integer = i To ProgramDetails.Directory.Length - 1
                                        ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                                    Next
                                    ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                                    Exit For
                                ElseIf ProgramDetails.Directory.Chars(i) = "-" And ProgramDetails.Directory.Chars(i - 1) = " " Then
                                    For x As Integer = i To ProgramDetails.Directory.Length - 1
                                        ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                                    Next
                                    ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                                    Exit For
                                End If
                            Catch
                            End Try
                        Next
                        If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                            My.Settings.prognames.Add(ProgramDetails.Name)
                            My.Settings.progdirs.Add(ProgramDetails.Directory)
                            My.Settings.progexts.Add(ProgramDetails.Extension)
                        Else
                            ProgramDetails = CheckDetails.CheckDetails(ProgramDetails)
check:                      If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                                My.Settings.prognames.Add(ProgramDetails.Name)
                                My.Settings.progdirs.Add(ProgramDetails.Directory)
                                My.Settings.progexts.Add(ProgramDetails.Extension)
                            Else
                                If MsgBox(ProgramDetails.Directory & " no longer exists. Would you like to remove this value from the registry?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                                    Dim Proc As New Process
                                    Dim ProcStartInfo As New ProcessStartInfo("C:\Windows\System32\cmd.exe", "/c REG DELETE " & """"c & "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Managed Startup" & """"c & " /v " & ProgramDetails.Name & " /f")
                                    ProcStartInfo.UseShellExecute = True
                                    ProcStartInfo.Verb = "runas"
                                    Proc.StartInfo = ProcStartInfo
                                    Proc.Start()
                                End If
                            End If
                        End If
                    ElseIf Not My.Settings.progdirs.Item(My.Settings.prognames.IndexOf(KeyName)) = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(KeyName) Then
                        Dim ProgramDetails As New ProgramDetails
                        ProgramDetails.Directory = My.Computer.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(KeyName)
                        ProgramDetails.Name = KeyName
                        For i As Integer = 0 To ProgramDetails.Directory.Length - 1
                            Try
                                If ProgramDetails.Directory.Chars(i) = "/" Then
                                    For x As Integer = i To ProgramDetails.Directory.Length - 1
                                        ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                                    Next
                                    ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                                    Exit For
                                ElseIf ProgramDetails.Directory.Chars(i) = "-" And ProgramDetails.Directory.Chars(i - 1) = " " Then
                                    For x As Integer = i To ProgramDetails.Directory.Length - 1
                                        ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                                    Next
                                    ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                                    Exit For
                                End If
                            Catch
                            End Try
                        Next
                        If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                            My.Settings.progdirs.Item((My.Settings.prognames.IndexOf(KeyName))) = ProgramDetails.Directory
                            My.Settings.progexts.Item((My.Settings.prognames.IndexOf(KeyName))) = ProgramDetails.Extension
                        Else
                            ProgramDetails = CheckDetails.CheckDetails(ProgramDetails)
check2:                     If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                                My.Settings.progdirs.Item((My.Settings.prognames.IndexOf(KeyName))) = ProgramDetails.Directory
                                My.Settings.progexts.Item((My.Settings.prognames.IndexOf(ProgramDetails.Name))) = ProgramDetails.Extension
                            Else
                                If MsgBox(ProgramDetails.Directory & " no longer exists. Would you like to remove this value from the registry?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                                    Dim Proc As New Process
                                    Dim ProcStartInfo As New ProcessStartInfo("C:\Windows\System32\cmd.exe", "/c REG DELETE " & """"c & "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Managed Startup" & """"c & " /v " & ProgramDetails.Name & " /f")
                                    ProcStartInfo.UseShellExecute = True
                                    ProcStartInfo.Verb = "runas"
                                    Proc.StartInfo = ProcStartInfo
                                    Proc.Start()
                                End If
                            End If
                        End If
                    End If
                End If
            Next
        Catch
            If My.Settings.prognames Is Nothing Then
                My.Settings.prognames = New ArrayList
                My.Settings.progdirs = New ArrayList
                My.Settings.progexts = New ArrayList
                My.Settings.Save()
            End If
            GoTo Loadfromregistry
        End Try

    End Sub

    Sub AddAllUsersRegistry()
        status = "Searching All Users Registry"
        Dim keynames() As String = My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValueNames
        Dim dirs As New ArrayList
        Dim dirsname As New ArrayList
        For Each Name As String In keynames
            dirsname.Add(Name)
            dirs.Add(My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(Name))
allcheckformarks: For i = 0 To dirs(dirs.Count - 1).Length - 1
                If dirs(dirs.Count - 1).Chars(i) = """"c Then
                    dirs(dirs.Count - 1) = dirs(dirs.Count - 1).Remove(i, 1)
                    GoTo allcheckformarks
                End If
            Next
        Next
        For Each Name As String In keynames
            checkprognames.Add(Name)
            If Not Name = "Startup Manager" And Not My.Settings.prognames.Contains(Name) Then
                Dim ProgramDetails As New ProgramDetails
                ProgramDetails.Directory = dirs(dirsname.IndexOf(Name))
                ProgramDetails.Name = Name
                For i As Integer = 0 To ProgramDetails.Directory.Length - 1
                    Try
                        If ProgramDetails.Directory.Chars(i) = "/" Then
                            For x As Integer = i To ProgramDetails.Directory.Length - 1
                                ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                            Next
                            ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                            Exit For
                        ElseIf ProgramDetails.Directory.Chars(i) = "-" And ProgramDetails.Directory.Chars(i - 1) = " " Then
                            For x As Integer = i To ProgramDetails.Directory.Length - 1
                                ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                            Next
                            ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                            Exit For
                        End If
                    Catch
                    End Try
                Next
                If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                    My.Settings.prognames.Add(Name)
                    My.Settings.progdirs.Add(ProgramDetails.Directory)
                    My.Settings.progexts.Add(ProgramDetails.Extension)
                Else
                    ProgramDetails = CheckDetails.CheckDetails(ProgramDetails)
check:              If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                        My.Settings.prognames.Add(Name)
                        My.Settings.progdirs.Add(ProgramDetails.Directory)
                        My.Settings.progexts.Add(ProgramDetails.Extension)
                    Else
                        If MsgBox(ProgramDetails.Directory & " no longer exists. Would you like to remove this value from the registry?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                            Dim Proc As New Process
                            Dim ProcStartInfo As New ProcessStartInfo("C:\Windows\System32\cmd.exe", "/c REG DELETE " & """"c & "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Managed Startup" & """"c & " /v " & Name & " /f")
                            ProcStartInfo.UseShellExecute = True
                            ProcStartInfo.Verb = "runas"
                            Proc.StartInfo = ProcStartInfo
                            Proc.Start()
                        End If
                    End If
                End If
            ElseIf Not My.Settings.progdirs.Item(My.Settings.prognames.IndexOf(Name)) = My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run\Managed Startup").GetValue(Name) Then
                Dim ProgramDetails As New ProgramDetails
                ProgramDetails.Directory = dirs(dirsname.IndexOf(Name))
                ProgramDetails.Name = Name
                For i As Integer = 0 To ProgramDetails.Directory.Length - 1
                    Try
                        If ProgramDetails.Directory.Chars(i) = "/" Then
                            For x As Integer = i To ProgramDetails.Directory.Length - 1
                                ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                            Next
                            ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                            Exit For
                        ElseIf ProgramDetails.Directory.Chars(i) = "-" And ProgramDetails.Directory.Chars(i - 1) = " " Then
                            For x As Integer = i To ProgramDetails.Directory.Length - 1
                                ProgramDetails.Extension += ProgramDetails.Directory.Chars(x)
                            Next
                            ProgramDetails.Directory = ProgramDetails.Directory.Remove(i, ProgramDetails.Directory.Length - i)
                            Exit For
                        End If
                    Catch
                    End Try
                Next
                If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                    My.Settings.progdirs.Item((My.Settings.prognames.IndexOf(Name))) = ProgramDetails.Directory
                    My.Settings.progexts.Item((My.Settings.prognames.IndexOf(Name))) = ProgramDetails.Extension
                Else
                    ProgramDetails = CheckDetails.CheckDetails(ProgramDetails)
check2:             If IO.File.Exists(ProgramDetails.Directory) Or ProgramDetails.Directory = "RUNDLL32.EXE" Then
                        My.Settings.progdirs.Item(My.Settings.prognames.IndexOf(Name)) = ProgramDetails.Directory
                        My.Settings.progexts.Item(My.Settings.prognames.IndexOf(Name)) = ProgramDetails.Extension
                    Else
                        If MsgBox(ProgramDetails.Directory & " no longer exists. Would you like to remove this value from the registry?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                            Dim Proc As New Process
                            Dim ProcStartInfo As New ProcessStartInfo("C:\Windows\System32\cmd.exe", "/c REG DELETE " & """"c & "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Managed Startup" & """"c & " /v " & Name & " /f")
                            ProcStartInfo.UseShellExecute = True
                            ProcStartInfo.Verb = "runas"
                            Proc.StartInfo = ProcStartInfo
                            Proc.Start()
                        End If
                    End If
                End If
            End If
        Next
    End Sub

    Sub AddtoArrays()
        AddCurrentUserRegistry()
        AddAllUsersRegistry()

        'Add from Current User Start Menu
        status = "Searching User Start Menu"
        Dim path As String = My.Computer.Registry.CurrentUser.OpenSubKey("Volatile Environment").GetValue("USERPROFILE") & "\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Managed Startup\"
        For Each item As String In System.IO.Directory.GetFiles(path)
            Dim nameext As String = item.Substring(path.Length)
            Dim name As String = ""
            Dim ext As String = ""
            For i As Integer = 0 To nameext.Length - 1
                If nameext(i) = "." Then
                    ext = nameext.Substring(i)
                    Exit For
                End If
                name += nameext(i)
            Next
            checkprognames.Add(name)
            If Not My.Settings.prognames.Contains(name) Then
                My.Settings.prognames.Add(name)
                My.Settings.progdirs.Add(path & name & ext)
                My.Settings.progexts.Add("")
            End If
        Next

        'Add from All Users Start Menu
        status = "Searching All Users Start Menu"
        For Each item As String In System.IO.Directory.GetFiles("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\All Managed Startup\")
            Dim nameext As String = item.Substring(73)
            Dim name As String = ""
            Dim ext As String = ""
            For i As Integer = 0 To nameext.Length - 1
                If nameext(i) = "." Then
                    ext = nameext.Substring(i)
                    Exit For
                End If
                name += nameext(i)
            Next
            checkprognames.Add(name)
            If Not My.Settings.prognames.Contains(name) Then
                My.Settings.prognames.Add(name)
                My.Settings.progdirs.Add("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\All Managed Startup\" & name & ext)
                My.Settings.progexts.Add("")
            End If
        Next
        My.Settings.Save()

        status = "Removing old items from list"
        Dim oldprognames As New ArrayList
        For Each item In My.Settings.prognames
            oldprognames.Add(item)
        Next
        For Each item In oldprognames
            If Not checkprognames.Contains(item) Then
                My.Settings.progexts.RemoveAt(My.Settings.prognames.IndexOf(item))
                My.Settings.progdirs.RemoveAt(My.Settings.prognames.IndexOf(item))
                My.Settings.prognames.Remove(item)
            End If
        Next
        My.Settings.Save()

        'Load arrays from Settings
        status = "Preparing Startup list"
        For Each item In My.Settings.prognames
            prognames(totalprogs) = item
            progsleftlist.Add(item)
            progdirs(totalprogs) = My.Settings.progdirs(totalprogs)
            progexts(totalprogs) = My.Settings.progexts(totalprogs)
            totalprogs += 1
        Next

        'Add all to progsleft
        progsleft = totalprogs
        progsleftlistchange = True
    End Sub

    Sub Launcher()
        launchallenabled = True
        Try
            status = "Begining Managed Startup"
            For i = 1 To 500
                progress = i
                System.Threading.Thread.Sleep(20)
            Next

            Dim CPULevel As Integer
            Dim DiskReadLevel As Integer
            Dim DiskWriteLevel As Integer
            Dim DiskTransferLevel As Integer

            Do Until NextProgInt = totalprogs
                overrideenabled = True
                CPULevel = 0
                For i = 0 To 20
                    CPULevel += CInt(Fix(CPUCounter.NextValue()))
                    Threading.Thread.Sleep(10)
                Next
                CPULevel /= 20
                If CPULevel > 100 Then CPULevel = 100

                Try
                    DiskReadLevel = 0
                    For i = 0 To 20
                        DiskReadLevel += CInt(Fix(DiskReadCounter.NextValue()))
                        Threading.Thread.Sleep(10)
                    Next
                    DiskReadLevel /= 20
                    DiskReadLevel /= 1024
                Catch
                End Try

                Try
                    DiskWriteLevel = 0
                    For i = 0 To 20
                        DiskWriteLevel += CInt(Fix(DiskWriteCounter.NextValue))
                        Threading.Thread.Sleep(10)
                    Next
                    DiskWriteLevel /= 20
                    DiskWriteLevel /= 1024
                Catch
                End Try

                Try
                    DiskTransferLevel = 0
                    For i = 0 To 20
                        DiskTransferLevel += CInt(Fix(DiskTransferCounter.NextValue))
                        Threading.Thread.Sleep(10)
                    Next
                    DiskTransferLevel /= 20
                Catch
                End Try

                progress = 0
                If Override = True Then
                    Override = False
                    GoTo launch
                End If
                If CPULevel > My.Settings.CPUThreshold Or DiskReadLevel > My.Settings.DRThreshold Or DiskWriteLevel > My.Settings.DWThreshold Or DiskTransferLevel > My.Settings.DTThreshold Then
                    If CPULevel > My.Settings.CPUThreshold Then
                        status = "Waiting for CPU Usage to Lower" & vbCr & "Current level: " & CPULevel & "% used"
                        waitingreason = waitingreasonenum.cpu
                    ElseIf DiskReadLevel > My.Settings.DRThreshold Then
                        status = "Waiting for Disk Reads to Lower" & vbCr & "Current level: " & DiskReadLevel & " KB /sec"
                        waitingreason = waitingreasonenum.disk
                    ElseIf DiskTransferLevel > My.Settings.DTThreshold Then
                        status = "Waiting for Disk Writes to Lower" & vbCr & "Current level: " & DiskWriteLevel & " KB /sec"
                        waitingreason = waitingreasonenum.disk
                    Else
                        status = "Waiting for Disk Transfer to Lower" & vbCr & "Current level: " & DiskTransferLevel & " Transfers /sec"
                        waitingreason = waitingreasonenum.disk
                    End If
                    waiting = True
                    System.Threading.Thread.Sleep(1000)
                Else
launch:             waiting = False
                    If Not prognames(NextProgInt) = "Startup Manager" Then
                        If IO.File.Exists(progdirs(NextProgInt)) Or progdirs(NextProgInt) = "RUNDLL32.EXE" Then
                            lastlaunchedprogram = prognames(NextProgInt)
                            progsleftlist.Remove(prognames(NextProgInt))
                            progsleftlistchange = True
                            status = "Launching: " & prognames(NextProgInt)
                            Try
                                If Debugger.IsAttached = False Then
                                    Dim shell As New Shell32.Shell
                                    shell.ShellExecute(progdirs(NextProgInt), progexts(NextProgInt))
                                End If
                            Catch ex As Exception
                                status = "Failed to launch: " & prognames(NextProgInt) & vbCr & "'" & ex.Message & "'"
                            End Try
                        Else
                            status = "Could not launch " & prognames(NextProgInt) & " because it no longer exists!"
                            If MsgBox("Could not launch " & prognames(NextProgInt) & " because it no longer exists!" & vbCr & "Would you like to remove it from the startup list?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                                My.Settings.prognames.RemoveAt(NextProgInt)
                                My.Settings.progdirs.RemoveAt(NextProgInt)
                                My.Settings.progexts.RemoveAt(NextProgInt)
                            End If
                        End If
                    End If
                    If Debugger.IsAttached = False Then
                        For i = 1 To 500
                            progress = i
                            System.Threading.Thread.Sleep(10)
                        Next
                    End If
                    progsleft -= 1
                    NextProgInt += 1
                End If
            Loop
            overrideenabled = False
            launchallenabled = False
            progress = 0
            status = "Checking start menu and registy for other programs"
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
        CHECK()
    End Sub

    Sub CHECK()
        Dim names() As String = My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").GetValueNames()
        Dim startnames() As String = System.IO.Directory.GetFiles("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup")
        MovefromUserRegistry()
        MovefromUserStartMenu()
        Try
            If Not startnames.Length = 0 _
            Or My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").ValueCount > 1 _
            Or Not My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run").GetValue("Startup Manager") = Reflection.Assembly.GetExecutingAssembly().Location() _
            Or Not My.Computer.Registry.LocalMachine.OpenSubKey("Software\Startup Manager\").GetValue("Version") = My.Application.Info.Version.ToString _
            Or Not names.Contains("Startup Manager") Then
                RunAAUSP.ShowDialog()
            End If
        Catch
            RunAAUSP.ShowDialog()
        End Try
        status = "Finished Managed Startup"
        Threading.Thread.Sleep(5000)
        closeme = True
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If progsleftlistchange = True Then
            progsleftlistchange = False
            Try
                If intaskbar = True Then TaskbarIcon.ShowBalloonTip(5000, "Launching:", lastlaunchedprogram, ToolTipIcon.Info)
            Catch
            End Try
            ListBox1.Items.Clear()
            For Each item In progsleftlist
                ListBox1.Items.Add(item)
            Next
        End If
        If waiting = True Then
            If waitingreason = waitingreasonenum.cpu Then
                TaskbarIcon.Icon = My.Resources.CPU
            Else
                TaskbarIcon.Icon = My.Resources.Disk
            End If
            ProgressBar1.Step = 50
            ProgressBar1.Style = ProgressBarStyle.Marquee
        Else
            TaskbarIcon.Icon = My.Resources.Icon
            ProgressBar1.Step = 500
            ProgressBar1.Style = ProgressBarStyle.Continuous
            ProgressBar1.Value = progress
        End If
        Label1.Text = status
        If Not progsleft <= 0 Then
            TaskbarIcon.Text = "Startup Manager: Program " & totalprogs - progsleft + 1 & " of " & totalprogs
            Me.Text = "Startup Manager: Program " & totalprogs - progsleft + 1 & " of " & totalprogs
        End If
        If closeme = True Then
            Me.Close()
        End If
        OverrideButton.Enabled = overrideenabled
        LaunchAll.Enabled = launchallenabled
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Hide()
        intaskbar = True
        TaskbarIcon.ShowBalloonTip(5000, "", "Startup Manager has been minimized to the taskbar", ToolTipIcon.Info)
    End Sub

    Private Sub TaskbarIcon_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TaskbarIcon.DoubleClick
        Me.Show()
        intaskbar = False
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        StartupOrder.ShowDialog()
    End Sub

    Private Sub ThresholdsButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ThresholdsButton.Click
        Thresholds.Show()
    End Sub

    Private Sub OverrideButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OverrideButton.Click
        Override = True
    End Sub

    Private Sub LaunchAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LaunchAll.Click
        launcherthread.Abort()
        Do Until launcherthread.IsAlive = False
            System.Threading.Thread.Sleep(100)
        Loop
        Do Until NextProgInt = totalprogs
            If Not prognames(NextProgInt) = "Startup Manager" Then
                If IO.File.Exists(progdirs(NextProgInt)) Or progdirs(NextProgInt) = "RUNDLL32.EXE" Then
                    lastlaunchedprogram = prognames(NextProgInt)
                    progsleftlist.Remove(prognames(NextProgInt))
                    progsleftlistchange = True
                    status = "Launching: " & prognames(NextProgInt)
                    Try
                        If Debugger.IsAttached = False Then
                            Dim shell As New Shell32.Shell
                            shell.ShellExecute(progdirs(NextProgInt), progexts(NextProgInt))
                        End If
                    Catch ex As Exception
                        status = "Failed to launch: " & prognames(NextProgInt) & vbCr & "'" & ex.Message & "'"
                    End Try
                Else
                    status = "Could not launch " & prognames(NextProgInt) & " because it no longer exists!"
                    If MsgBox("Could not launch " & prognames(NextProgInt) & " because it no longer exists!" & vbCr & "Would you like to remove it from the startup list?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                        My.Settings.prognames.RemoveAt(NextProgInt)
                        My.Settings.progdirs.RemoveAt(NextProgInt)
                        My.Settings.progexts.RemoveAt(NextProgInt)
                    End If
                End If
            End If
            progsleft -= 1
            NextProgInt += 1
        Loop
        progress = 0
        status = "Checking start menu and registy for other programs"
        CHECK()
    End Sub
End Class
